import json

from django.contrib.auth import login
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from QQLoginTool.QQtool import OAuthQQ

import meiduo_mall.settings
from apps.users.models import User
from meiduo_mall import settings
from apps.oauth.models import OAuthQQUser
# Create your views here.

"""
生成用户绑定链接.
前端: 用户点击qq登录图标， 前端发送一个axios请求 /qq/authorization/? next=xxx.
后端:
    请求.
    业务逻辑. 调用QQLoginTool 生成跳转链接
    响应:    返回跳转链接 {"code":0, 'qq_login_url':'xxx'}
    路由: /qq/authorization/?
    步骤:    
        1. 调用QQLoginTool实例.
        2. 调用对象的方法生成跳转链接.
        3. 返回响应
"""


class QQLoginURLView(View):
    def get(self, request):

        print(request.GET.get('next'))

        qq_inst = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                          client_secret=settings.QQ_CLIENT_SECRET,
                          redirect_uri=settings.QQ_REDIRECT_URL,
                          state='xxxx')

        qq_login_url = qq_inst.get_qq_url()
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'login_url': qq_login_url})

    def post(self, request):
        data = json.loads(request.body.decode())
        mobile = data.get('mobile')
        password = data.get('password')
        sms_code = data.get('sms_code')
        openid = data.get('access_token')

        if not all([mobile, password, sms_code, openid]):
            return JsonResponse({"code": 400, "errmsg": "错误参数"})
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user = User.objects.create_user(username=mobile, mobile=mobile, password=password)
        else:
            if not user.check_password(password):
                return JsonResponse({"code": 400, "errmsg": "账号或密码错误"})

        OAuthQQUser.objects.create(user=user, openid=openid)
        login(request, user)
        response = JsonResponse({'code':0, 'errmsg': 'ok'})
        response.set_cookie('username', user.username)
        return response



"""
需求: 获取code, 通过code换取token, 再根据token换取openid.
前端: 客户端通过网页获取code, 发送后端.
后端:
    请求:         获取code.
    业务逻辑.      通过code获取token. 
    响应          
    路由      get: oauth_callback/?code=xxxxx.
    步骤      
            1. 获取code
            2. 通过code换取token
            3. 通过 token 换取openid
            4. 根据openid进行判断.
            5. 如果没有绑定，则进行绑定
            7. 如果绑定，进行登录.

"""


class OauthQQView(View):
    def get(self, request):
        # 1.获取code
        code = request.GET.get('code')
        if code is None:
            return JsonResponse({"code": 400, "errmsg": "错误参数"})
        # 2.通过code换取token
        qq_inst = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                          client_secret=settings.QQ_CLIENT_SECRET,
                          redirect_uri=settings.QQ_REDIRECT_URL,
                          state='xxxx')
        token = qq_inst.get_access_token(code)
        # 3.通过token换取openid
        openid = qq_inst.get_open_id(token)
        # 4.根据openid进行判断.
        try:
            qquser = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 不存在.
            response = JsonResponse({'code':400, 'access_token': openid})
            return response
        else:
            # 存在
            # 6.如果绑定，进行登录.
            # 6.1 设置sessiion.
            login(request, qquser.user)
            # 6.2 设置cookie.
            response = JsonResponse({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('username', qquser.user.username)
            return response

        # 5.如果没有绑定，则进行绑定
        # 6.如果绑定，进行登录.
        pass

"""
绑定账户需求分析
需求：
    QQ(openid)和美多账号id.
    前端提交， 手机号， 密码， 短信验证码， openid.
前端:
    前端提交axios请求.
后端:
    请求: 获取请求参数.
    业务逻辑: 绑定，完成状态保持.
    返回. post. code=0,
    路由: auth_callback/
    
"""

"""加密."""

def sign_str_test():
    from itsdangerous import Serializer

    # 创建 Serializer 实例
    s = Serializer(secret_key='my_secret_key')

    # 生成签名数据
    signed_data = s.dumps({'user_id': 123})
    print(f"Signed Data: {signed_data}")

    # 验证并解码数据
    try:
        original_data = s.loads(signed_data)
        print(f"Original Data: {original_data}")
    except Exception as e:
        print(f"Invalid Signature: {e}")


def unsign_test_with_expired():
    from itsdangerous import TimedSerializer

    # 创建带有过期时间的 TimedSerializer 实例
    ts = TimedSerializer(secret_key='my_secret_key')

    # 生成带有过期时间的签名数据（有效期为 60 秒）
    signed_data = ts.dumps({'user_id': 123})
    print(f"Signed Data with Expiration: {signed_data}")

    # 验证签名数据（未过期时）
    try:
        original_data = ts.loads(signed_data, max_age=60)  # 60秒内有效
        print(f"Original Data: {original_data}")
    except Exception as e:
        print(f"Invalid or Expired Signature: {e}")

